package Busquedas;

import Problemas.Problema;
import java.util.ArrayList;

/**
 * Clase para implementar la busqueda heuristica de A*.
 */
public class EscaladaSimple extends Busqueda{

    /**
	 Hereda de la clase problema,introducimos un parametro cerrados para llevar los nodos cerrados
	 */
	public EscaladaSimple(Problema p) {
		super(p);

	}


    @Override
	public ArrayList<Estado> buscar(boolean controlCiclos) {
		long tiempo1=System.currentTimeMillis();
		Nodo nodo = this.getNodo();
		Nodo hijo;
        nodo.setCosteAcumulado(0);
		nodo.setValorHeuristico(this.getProblema().funcionHeuristica(nodo.getEstado()));
        abiertos.add(nodo);//añadir aki??
		try{
			while (!this.getProblema().estadoFinal(nodo.getEstado())&& !(abiertos.isEmpty())){

                vaciaAbiertos();
				for (int op = 0; op < this.getProblema().getnumOper(); op++){
					if (nodo.getOperadoresAplicados()[op]!=1){
						Estado e = this.getProblema().aplicaOperador(nodo.getEstado(),op);
						if (e != null ){
                            hijo = nodo.anadeHijo(op,e,this.getProblema().getCosteOperador(op));
                            hijo.setValorHeuristico(this.getProblema().funcionHeuristica(hijo.getEstado()));
                            abiertos.add(hijo);
						}
					}
				}
				contadorNodos++;
				if (contadorNodos>maxContadorNodos) return null;
                        if(!abiertos.isEmpty()){
                            nodo = abiertos.get(indiceMejorqueActual(nodo));
                        }
                        else
                            return null;
			}
		//	this.dibujaNodos(nodo.getNumMaxHijos(),nodo,nodo.getEstado());
			this.generaCamino(nodo);
			long tiempo2=System.currentTimeMillis();
			this.setTiempoTotal((tiempo2-tiempo1));
			return camino;
		}
            catch(OutOfMemoryError e){
			System.out.println(abiertos.size());
			abiertos = null;
			return null;
		}
	}



	/**
	 * Metodo que devuelve el primer indice con coste heuristico menor que el actual
	 */
	public int indiceMejorqueActual(Nodo n){
		int indiceMejor = 0;
		int i = 0;
		int menorValor = (abiertos.get(0).getValorHeuristico()+abiertos.get(0).getCosteAcumulado());
		while (i < abiertos.size()){
			if (n.getValorHeuristico() > (abiertos.get(i).getValorHeuristico())){
				return i;
			}else{
				i++;
			}
		}
		return indiceMejor;
	}
	/**
	 * Metodo que vacia la cola de abiertos porque solo se fija en el nodo actual
	 */
    private void vaciaAbiertos() {
        while(!(abiertos.isEmpty())){
            abiertos.remove(0);
        }
    }

}
